<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js 开发流程关系图</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <header>
            <h1>Three.js 开发流程关系图</h1>
            <p>从基础骨架搭建到调试优化的完整开发流程</p>
        </header>

        <div class="flow-container">
            <!-- 阶段1: 基础骨架搭建 -->
            <div class="stage" id="stage1">
                <div class="stage-header">
                    <h2>1. 基础骨架搭建</h2>
                    <span class="stage-badge">main.js</span>
                </div>
                <div class="stage-content">
                    <div class="step-group">
                        <h3>初始化设置</h3>
                        <div class="steps">
                            <div class="step">获取 &lt;canvas&gt; 元素引用
                                <div class="step-detail">const canvas = document.querySelector('#canvas');<br>// 或动态创建: const canvas = document.createElement('canvas');<br>// 设置尺寸: canvas.width = window.innerWidth; canvas.height = window.innerHeight;</div>
                            </div>
                            <div class="step">创建 WebGLRenderer 实例
                                <div class="step-detail">const renderer = new THREE.WebGLRenderer({<br>&nbsp;&nbsp;canvas: canvas,<br>&nbsp;&nbsp;antialias: true, // 抗锯齿<br>&nbsp;&nbsp;alpha: true, // 透明背景<br>&nbsp;&nbsp;powerPreference: 'high-performance' // 性能优先<br>});</div>
                            </div>
                            <div class="step">设置渲染器尺寸和像素比
                                <div class="step-detail">renderer.setSize(window.innerWidth, window.innerHeight);<br>renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // 限制最大像素比<br>renderer.outputColorSpace = THREE.SRGBColorSpace; // 色彩空间</div>
                            </div>
                            <div class="step">创建 Scene 实例
                                <div class="step-detail">const scene = new THREE.Scene();<br>scene.background = new THREE.Color(0x87CEEB); // 设置背景色<br>// 或使用环境贴图: scene.background = cubeTexture;</div>
                            </div>
                            <div class="step">创建 Camera 实例
                                <div class="step-detail">const camera = new THREE.PerspectiveCamera(<br>&nbsp;&nbsp;75, // fov 视野角度<br>&nbsp;&nbsp;window.innerWidth / window.innerHeight, // aspect 宽高比<br>&nbsp;&nbsp;0.1, // near 近裁剪面<br>&nbsp;&nbsp;1000 // far 远裁剪面<br>);<br>camera.position.set(0, 0, 5);</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>基础配置</h3>
                        <div class="steps">
                            <div class="step">创建基础光源
                                <div class="step-detail">// 环境光提供整体亮度<br>const ambientLight = new THREE.AmbientLight(0x404040, 0.6);<br>scene.add(ambientLight);<br><br>// 方向光提供主要照明和阴影<br>const directionalLight = new THREE.DirectionalLight(0xffffff, 1);<br>directionalLight.position.set(5, 5, 5);<br>scene.add(directionalLight);</div>
                            </div>
                            <div class="step">初始化控制器
                                <div class="step-detail">import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';<br><br>const controls = new OrbitControls(camera, renderer.domElement);<br>controls.enableDamping = true; // 阻尼效果<br>controls.dampingFactor = 0.05;<br>controls.enableZoom = true;<br>controls.autoRotate = false;</div>
                            </div>
                            <div class="step">定义 resize 事件处理
                                <div class="step-detail">function onWindowResize() {<br>&nbsp;&nbsp;camera.aspect = window.innerWidth / window.innerHeight;<br>&nbsp;&nbsp;camera.updateProjectionMatrix();<br>&nbsp;&nbsp;renderer.setSize(window.innerWidth, window.innerHeight);<br>}<br><br>window.addEventListener('resize', onWindowResize);</div>
                            </div>
                            <div class="step highlight">启动动画循环
                                <div class="step-detail">function animate() {<br>&nbsp;&nbsp;requestAnimationFrame(animate);<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;// 更新控制器（如果使用）<br>&nbsp;&nbsp;if (controls) controls.update();<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;// 渲染场景<br>&nbsp;&nbsp;renderer.render(scene, camera);<br>}<br><br>animate(); // 启动动画循环</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="arrow">↓</div>

            <!-- 阶段2: 场景构建 -->
            <div class="stage" id="stage2">
                <div class="stage-header">
                    <h2>2. 场景构建</h2>
                    <span class="stage-badge">App.js / SceneManager.js</span>
                </div>
                <div class="stage-content">
                    <div class="step-group">
                        <h3>创建物体</h3>
                        <div class="steps">
                            <div class="step">创建几何体 (Geometry)
                                <div class="step-detail">// 基础几何体<br>const boxGeometry = new THREE.BoxGeometry(1, 1, 1);<br>const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);<br>const planeGeometry = new THREE.PlaneGeometry(2, 2);<br><br>// 自定义几何体<br>const customGeometry = new THREE.BufferGeometry();<br>const vertices = new Float32Array([...]);<br>customGeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));</div>
                            </div>
                            <div class="step">创建材质 (Material)
                                <div class="step-detail">// 基础材质（不受光照影响）<br>const basicMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });<br><br>// 标准材质（PBR，推荐）<br>const standardMaterial = new THREE.MeshStandardMaterial({<br>&nbsp;&nbsp;color: 0x00ff00,<br>&nbsp;&nbsp;metalness: 0.5,<br>&nbsp;&nbsp;roughness: 0.5<br>});<br><br>// Phong材质（经典光照模型）<br>const phongMaterial = new THREE.MeshPhongMaterial({ color: 0x0000ff });</div>
                            </div>
                            <div class="step">组合成 Mesh 并添加到场景
                                <div class="step-detail">const mesh = new THREE.Mesh(geometry, material);<br><br>// 设置位置、旋转、缩放<br>mesh.position.set(0, 0, 0);<br>mesh.rotation.set(0, Math.PI / 4, 0);<br>mesh.scale.set(1, 1, 1);<br><br>// 添加到场景<br>scene.add(mesh);</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>资源加载 (异步)</h3>
                        <div class="steps">
                            <div class="step">使用 TextureLoader 加载纹理
                                <div class="step-detail">const textureLoader = new THREE.TextureLoader();<br><br>// 基础纹理加载<br>const texture = textureLoader.load('path/to/texture.jpg');<br><br>// 设置纹理属性<br>texture.wrapS = THREE.RepeatWrapping;<br>texture.wrapT = THREE.RepeatWrapping;<br>texture.repeat.set(2, 2);<br>texture.minFilter = THREE.LinearMipmapLinearFilter;<br>texture.magFilter = THREE.LinearFilter;</div>
                            </div>
                            <div class="step">使用 GLTFLoader/FBXLoader 加载模型
                                <div class="step-detail">import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';<br><br>const gltfLoader = new GLTFLoader();<br>gltfLoader.load(<br>&nbsp;&nbsp;'path/to/model.gltf',<br>&nbsp;&nbsp;(gltf) => {<br>&nbsp;&nbsp;&nbsp;&nbsp;const model = gltf.scene;<br>&nbsp;&nbsp;&nbsp;&nbsp;model.scale.setScalar(0.5);<br>&nbsp;&nbsp;&nbsp;&nbsp;scene.add(model);<br>&nbsp;&nbsp;},<br>&nbsp;&nbsp;(progress) => console.log('Loading progress:', progress),<br>&nbsp;&nbsp;(error) => console.error('Loading error:', error)<br>);</div>
                            </div>
                            <div class="step important">处理加载完成回调
                                <div class="step-detail">// 使用 LoadingManager 统一管理加载状态<br>const loadingManager = new THREE.LoadingManager();<br><br>loadingManager.onStart = (url, loaded, total) => {<br>&nbsp;&nbsp;console.log('开始加载:', url);<br>};<br><br>loadingManager.onProgress = (url, loaded, total) => {<br>&nbsp;&nbsp;const progress = (loaded / total * 100) + '%';<br>&nbsp;&nbsp;console.log('加载进度:', progress);<br>};<br><br>loadingManager.onLoad = () => {<br>&nbsp;&nbsp;console.log('所有资源加载完成');<br>};</div>
                            </div>
                            <div class="step">配置阴影和材质
                                <div class="step-detail">// 启用渲染器阴影<br>renderer.shadowMap.enabled = true;<br>renderer.shadowMap.type = THREE.PCFSoftShadowMap;<br><br>// 设置光源阴影<br>directionalLight.castShadow = true;<br>directionalLight.shadow.mapSize.setScalar(2048);<br><br>// 设置物体阴影属性<br>mesh.castShadow = true; // 投射阴影<br>groundMesh.receiveShadow = true; // 接收阴影</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>环境设置</h3>
                        <div class="steps">
                            <div class="step">添加天空盒或环境贴图
                                <div class="step-detail">const cubeTextureLoader = new THREE.CubeTextureLoader();<br>const cubeTexture = cubeTextureLoader.load([<br>&nbsp;&nbsp;'px.jpg', 'nx.jpg', // 正X, 负X<br>&nbsp;&nbsp;'py.jpg', 'ny.jpg', // 正Y, 负Y<br>&nbsp;&nbsp;'pz.jpg', 'nz.jpg'  // 正Z, 负Z<br>]);<br><br>scene.background = cubeTexture;<br>scene.environment = cubeTexture; // 环境光照<br><br>// HDRI环境贴图（推荐）<br>import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';<br><br>const rgbeLoader = new RGBELoader();<br>rgbeLoader.load('path/to/environment.hdr', (texture) => {<br>&nbsp;&nbsp;texture.mapping = THREE.EquirectangularReflectionMapping;<br>&nbsp;&nbsp;scene.background = texture;<br>&nbsp;&nbsp;scene.environment = texture;<br>});</div>
                            </div>
                            <div class="step">添加雾效果
                                <div class="step-detail">// 线性雾效果<br>scene.fog = new THREE.Fog(0xcccccc, 10, 100);<br><br>// 指数雾效果（更自然）<br>scene.fog = new THREE.FogExp2(0xcccccc, 0.02);<br><br>// 雾的颜色通常与背景色一致<br>scene.background = new THREE.Color(0xcccccc);</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="arrow">↓</div>

            <!-- 阶段3: 交互性实现 -->
            <div class="stage" id="stage3">
                <div class="stage-header">
                    <h2>3. 交互性实现</h2>
                    <span class="stage-badge">Interaction</span>
                </div>
                <div class="stage-content">
                    <div class="step-group">
                        <h3>控制器增强</h3>
                        <div class="steps">
                            <div class="step">配置 OrbitControls 基础参数
                                <div class="step-detail">// 阻尼设置（平滑效果）<br>controls.enableDamping = true;<br>controls.dampingFactor = 0.05;<br><br>// 功能开关<br>controls.enablePan = true; // 平移<br>controls.enableZoom = true; // 缩放<br>controls.enableRotate = true; // 旋转<br><br>// 自动旋转<br>controls.autoRotate = false;<br>controls.autoRotateSpeed = 2.0;</div>
                            </div>
                            <div class="step">设置距离和角度限制
                                <div class="step-detail">// 距离限制<br>controls.minDistance = 1;<br>controls.maxDistance = 50;<br><br>// 垂直角度限制（防止翻转）<br>controls.minPolarAngle = 0; // 最小仰角<br>controls.maxPolarAngle = Math.PI; // 最大仰角<br><br>// 水平角度限制（可选）<br>controls.minAzimuthAngle = -Infinity;<br>controls.maxAzimuthAngle = Infinity;</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>射线投射 (Raycaster)</h3>
                        <div class="steps">
                            <div class="step">创建 Raycaster 和鼠标向量
                                <div class="step-detail">const raycaster = new THREE.Raycaster();<br>const mouse = new THREE.Vector2();<br>const intersectableObjects = []; // 可交互物体数组</div>
                            </div>
                            <div class="step">监听鼠标/触摸事件
                                <div class="step-detail">// 鼠标点击事件<br>canvas.addEventListener('click', onMouseClick);<br>canvas.addEventListener('mousemove', onMouseMove);<br><br>// 触摸事件支持<br>canvas.addEventListener('touchstart', onTouchStart);<br>canvas.addEventListener('touchmove', onTouchMove);</div>
                            </div>
                            <div class="step">屏幕坐标转换为标准化坐标
                                <div class="step-detail">function updateMousePosition(event) {<br>&nbsp;&nbsp;const rect = canvas.getBoundingClientRect();<br>&nbsp;&nbsp;mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;<br>&nbsp;&nbsp;mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;<br>}</div>
                            </div>
                            <div class="step">射线投射检测交点
                                <div class="step-detail">function checkIntersections() {<br>&nbsp;&nbsp;raycaster.setFromCamera(mouse, camera);<br>&nbsp;&nbsp;const intersects = raycaster.intersectObjects(intersectableObjects, true);<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;if (intersects.length > 0) {<br>&nbsp;&nbsp;&nbsp;&nbsp;const selectedObject = intersects[0].object;<br>&nbsp;&nbsp;&nbsp;&nbsp;const point = intersects[0].point;<br>&nbsp;&nbsp;&nbsp;&nbsp;// 处理选中逻辑<br>&nbsp;&nbsp;}<br>}</div>
                            </div>
                            <div class="step">实现交互效果
                                <div class="step-detail">// 高亮效果<br>function highlightObject(object) {<br>&nbsp;&nbsp;object.material.emissive.setHex(0x444444);<br>}<br><br>// 取消高亮<br>function unhighlightObject(object) {<br>&nbsp;&nbsp;object.material.emissive.setHex(0x000000);<br>}<br><br>// 拖拽实现<br>let isDragging = false;<br>let dragObject = null;</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>自定义事件</h3>
                        <div class="steps">
                            <div class="step">键盘事件监听
                                <div class="step-detail">const keys = {};<br><br>// 键盘按下事件<br>document.addEventListener('keydown', (event) => {<br>&nbsp;&nbsp;keys[event.code] = true;<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;switch(event.code) {<br>&nbsp;&nbsp;&nbsp;&nbsp;case 'KeyW': moveForward(); break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case 'KeyS': moveBackward(); break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case 'KeyA': moveLeft(); break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case 'KeyD': moveRight(); break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case 'Space': jump(); break;<br>&nbsp;&nbsp;}<br>});<br><br>// 键盘释放事件<br>document.addEventListener('keyup', (event) => {<br>&nbsp;&nbsp;keys[event.code] = false;<br>});</div>
                            </div>
                            <div class="step">按钮事件处理
                                <div class="step-detail">// HTML按钮事件绑定<br>document.getElementById('playButton').addEventListener('click', () => {<br>&nbsp;&nbsp;playAnimation();<br>});<br><br>document.getElementById('resetButton').addEventListener('click', () => {<br>&nbsp;&nbsp;resetScene();<br>});<br><br>// 动态创建UI控制面板<br>function createControlPanel() {<br>&nbsp;&nbsp;const panel = document.createElement('div');<br>&nbsp;&nbsp;panel.style.position = 'absolute';<br>&nbsp;&nbsp;panel.style.top = '10px';<br>&nbsp;&nbsp;panel.style.left = '10px';<br>&nbsp;&nbsp;document.body.appendChild(panel);<br>}</div>
                            </div>
                            <div class="step">触发场景变化
                                <div class="step-detail">// 场景切换函数<br>function switchScene(sceneType) {<br>&nbsp;&nbsp;switch(sceneType) {<br>&nbsp;&nbsp;&nbsp;&nbsp;case 'day':<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scene.background = new THREE.Color(0x87CEEB);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;directionalLight.intensity = 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;case 'night':<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scene.background = new THREE.Color(0x000011);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;directionalLight.intensity = 0.1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;}<br>}<br><br>// 物体属性动态修改<br>function changeObjectColor(object, color) {<br>&nbsp;&nbsp;object.material.color.setHex(color);<br>}</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="arrow">↓</div>

            <!-- 阶段4: 动画实现 -->
            <div class="stage" id="stage4">
                <div class="stage-header">
                    <h2>4. 动画实现</h2>
                    <span class="stage-badge">Animation</span>
                </div>
                <div class="stage-content">
                    <div class="step-group">
                        <h3>属性动画</h3>
                        <div class="steps">
                            <div class="step">在 animate() 中修改物体属性
                                <div class="step-detail">使用 Clock 获取时间差，基于时间的动画更新</div>
                            </div>
                            <div class="step">position, rotation, scale 变化
                                <div class="step-detail">mesh.rotation.y += 0.01; mesh.position.y = Math.sin(time) * 2</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>关键帧动画</h3>
                        <div class="steps">
                            <div class="step">使用 AnimationMixer
                                <div class="step-detail">const mixer = new THREE.AnimationMixer(model); 管理动画状态</div>
                            </div>
                            <div class="step">创建 AnimationAction
                                <div class="step-detail">const action = mixer.clipAction(clip); action.play(); 设置循环模式</div>
                            </div>
                            <div class="step">在 animate() 中更新 mixer
                                <div class="step-detail">mixer.update(deltaTime); 每帧更新动画状态</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>第三方动画库</h3>
                        <div class="steps">
                            <div class="step">使用 Tween.js 库
                                <div class="step-detail">new TWEEN.Tween(mesh.position).to({x: 5}, 2000).easing(TWEEN.Easing.Quadratic.Out).start()</div>
                            </div>
                            <div class="step">链式动画控制
                                <div class="step-detail">链式调用、缓动函数、回调函数、动画组合与序列控制</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="arrow">↓</div>

            <!-- 阶段5: 视觉效果增强 -->
            <div class="stage" id="stage5">
                <div class="stage-header">
                    <h2>5. 视觉效果增强</h2>
                    <span class="stage-badge">Enhancement</span>
                </div>
                <div class="stage-content">
                    <div class="step-group">
                        <h3>阴影系统</h3>
                        <div class="steps">
                            <div class="step">启用渲染器阴影
                                <div class="step-detail">renderer.shadowMap.enabled = true; shadowMap.type = PCFSoftShadowMap</div>
                            </div>
                            <div class="step">设置光源和物体阴影属性
                                <div class="step-detail">light.castShadow = true; mesh.castShadow/receiveShadow = true</div>
                            </div>
                            <div class="step">调整阴影参数
                                <div class="step-detail">shadow.mapSize, shadow.camera.near/far, shadow.bias</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>后处理 (EffectComposer)</h3>
                        <div class="steps">
                            <div class="step">创建 EffectComposer
                                <div class="step-detail">const composer = new EffectComposer(renderer); 管理后处理通道</div>
                            </div>
                            <div class="step">添加 RenderPass
                                <div class="step-detail">const renderPass = new RenderPass(scene, camera); 基础渲染通道</div>
                            </div>
                            <div class="step">添加效果通道
                                <div class="step-detail">BloomPass, SSAOPass, OutlinePass, FilmPass 等特效</div>
                            </div>
                            <div class="step">替换 renderer.render()
                                <div class="step-detail">composer.render(); 在动画循环中调用</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>特殊效果</h3>
                        <div class="steps">
                            <div class="step">粒子系统 (Points)
                                <div class="step-detail">BufferGeometry + PointsMaterial, 大量粒子渲染优化</div>
                            </div>
                            <div class="step">自定义着色器
                                <div class="step-detail">ShaderMaterial, 顶点着色器(GLSL), 片段着色器, uniforms</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="arrow">↓</div>

            <!-- 阶段6: 调试与优化 -->
            <div class="stage" id="stage6">
                <div class="stage-header">
                    <h2>6. 调试与优化</h2>
                    <span class="stage-badge">Debug & Optimize</span>
                </div>
                <div class="stage-content">
                    <div class="step-group">
                        <h3>调试工具</h3>
                        <div class="steps">
                            <div class="step">console.log 基本输出
                                <div class="step-detail">输出物体属性、位置、状态等信息进行基础调试</div>
                            </div>
                            <div class="step">浏览器开发者工具
                                <div class="step-detail">使用 Console、Network、Performance 面板分析问题</div>
                            </div>
                            <div class="step important">lil-gui / dat.GUI 控制面板
                                <div class="step-detail">const gui = new GUI(); gui.add(object, 'property'); 实时调整参数</div>
                            </div>
                            <div class="step">Stats.js 性能监控
                                <div class="step-detail">const stats = new Stats(); stats.begin(); stats.end(); 监控FPS和内存</div>
                            </div>
                            <div class="step">辅助对象 (Helpers)
                                <div class="step-detail">AxesHelper, GridHelper, CameraHelper, DirectionalLightHelper</div>
                            </div>
                        </div>
                    </div>
                    <div class="step-group">
                        <h3>性能优化</h3>
                        <div class="steps">
                            <div class="step">减少 Draw Calls
                                <div class="step-detail">合并几何体、使用 InstancedMesh、批量渲染相同材质物体</div>
                            </div>
                            <div class="step">优化几何体和纹理
                                <div class="step-detail">降低多边形数量、压缩纹理格式、使用 mipmaps、合理设置纹理尺寸</div>
                            </div>
                            <div class="step">优化材质和光源
                                <div class="step-detail">减少光源数量、使用简单材质、避免透明材质、合理使用阴影</div>
                            </div>
                            <div class="step">内存管理 (dispose)
                                <div class="step-detail">geometry.dispose(); material.dispose(); texture.dispose(); 及时释放资源</div>
                            </div>
                            <div class="step">视锥体剔除 (Frustum Culling)
                                <div class="step-detail">object.frustumCulled = true; 自动剔除视野外物体</div>
                            </div>
                            <div class="step">LOD (Level of Detail)
                                <div class="step-detail">根据距离切换模型精度，THREE.LOD 对象管理不同细节层次</div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 侧边栏工具提示 -->
        <div class="sidebar">
            <div class="tool-tips">
                <h3>关键提示</h3>
                <div class="tip">
                    <h4>🔧 调试必备</h4>
                    <p>lil-gui 是调试 Three.js 应用的神器，可以实时调整参数</p>
                </div>
                <div class="tip">
                    <h4>⚡ 性能优化</h4>
                    <p>始终关注 Draw Calls 数量，这是性能的关键指标</p>
                </div>
                <div class="tip">
                    <h4>🎯 异步加载</h4>
                    <p>模型和纹理加载是异步的，务必在回调中处理</p>
                </div>
                <div class="tip">
                    <h4>🔄 动画循环</h4>
                    <p>requestAnimationFrame 是动画的核心，确保正确实现</p>
                </div>
            </div>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>